﻿using Raffles.OA.Data;
using Raffles.OA.Utility;
using System.Collections.Generic;
using System.Linq;

namespace Raffles.OA.WebApp
{
    public class MenuHelper
    {
        public static List<WebMenuDto> GetWebMenu()
        {
            OperatorModel operatorModel = OperatorProvider.Provider.GetCurrent();
            List<WebMenuDto> menus = null;
            using (var _dbContext = ReportDB.Db)
            {
                menus = CacheHelper.GetCache($"{operatorModel.Account}_{operatorModel.Id}") as List<WebMenuDto>;
                if (menus == null)
                {
                    if (operatorModel.IsSystem)
                    {
                        menus = _dbContext.Queryable<Menu>().Where(x => !x.DeletedMark && x.EnabledMark)
                                                            .Select(x => new WebMenuDto { Id = x.Id, ParentId = x.ParentId, Type = x.Type, Name = x.Name, UrlAddress = x.UrlAddress, Icon = x.Icon, DisplayOrder = x.DisplayOrder })
                                                            .ToList();
                    }
                    else
                    {
                        //获取当前用户拥有的菜单权限(这里取用户权限和角色权限并集)
                        List<WebMenuDto> roleMenus = _dbContext.Queryable<User, UserRole, Role, RoleMenu, Menu>
                                            ((u, ur, r, rm, m) => u.Id == ur.UserId && ur.RoleId == r.Id && r.Id == rm.RoleId && rm.MenuId == m.Id)
                                            .Where((u, ur, r, rm, m) => !u.DeletedMark && u.Id == OperatorProvider.Provider.GetCurrent().Id && !r.DeletedMark && r.EnabledMark && m.EnabledMark && !m.DeletedMark && m.Type != (int)MenuTypeEnum.Button)
                                            .Select((u, ur, r, rm, m) => new WebMenuDto { Id = m.Id, ParentId = m.ParentId, Type = m.Type, Name = m.Name, UrlAddress = m.UrlAddress, Icon = m.Icon, DisplayOrder = m.DisplayOrder })
                                            .ToList();
                        List<WebMenuDto> userMenus = _dbContext.Queryable<User, RoleMenu, Menu>
                                            ((u, rm, m) => u.Id == rm.UserId && rm.MenuId == m.Id)
                                            .Where((u, rm, m) => !u.DeletedMark && u.Id == OperatorProvider.Provider.GetCurrent().Id && m.EnabledMark && !m.DeletedMark && m.Type != (int)MenuTypeEnum.Button)
                                            .Select((u, rm, m) => new WebMenuDto { Id = m.Id, ParentId = m.ParentId, Type = m.Type, Name = m.Name, UrlAddress = m.UrlAddress, Icon = m.Icon, DisplayOrder = m.DisplayOrder })
                                            .ToList();
                        menus = roleMenus.Concat(userMenus).GroupBy(x => new { x.Id, x.ParentId, x.Type, x.Name, x.UrlAddress, x.Icon, x.DisplayOrder }).Select(x => x.First()).ToList();
                    }
                    CacheHelper.SetCache($"{operatorModel.Account}_{operatorModel.Id}", menus);
                    menus = CacheHelper.GetCache($"{operatorModel.Account}_{operatorModel.Id}") as List<WebMenuDto>;
                }
                menus = menus.GroupBy(x => new { x.Id, x.ParentId, x.Type, x.Name, x.UrlAddress, x.Icon, x.IsActive, x.DisplayOrder })
                             .OrderBy(x => x.Key.DisplayOrder)
                             .Select(x => new WebMenuDto { Id = x.Key.Id, ParentId = x.Key.ParentId, Type = x.Key.Type, Name = x.Key.Name, UrlAddress = x.Key.UrlAddress, Icon = x.Key.Icon, DisplayOrder = x.Key.DisplayOrder }).ToList();
                return menus;
            }
        }
    }
}